home *** CD-ROM | disk | FTP | other *** search
/ Download Now 8 / Download Now V8.iso / Program / InternetTools / ApacheWebServer1.3.6 / apache_1_3_6_win32.exe / _SETUP.1 / htdigest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-17  |  4.5 KB  |  206 lines

  1. /******************************************************************************
  2.  ******************************************************************************
  3.  * NOTE! This program is not safe as a setuid executable!  Do not make it
  4.  * setuid!
  5.  ******************************************************************************
  6.  *****************************************************************************/
  7. /*
  8.  * htdigest.c: simple program for manipulating digest passwd file for Apache
  9.  *
  10.  * by Alexei Kosut, based on htpasswd.c, by Rob McCool
  11.  */
  12.  
  13. #include "ap_config.h"
  14. #include <sys/types.h>
  15. #if defined(MPE) || defined(QNX)
  16. #include <signal.h>
  17. #else
  18. #include <sys/signal.h>
  19. #endif
  20. #include "ap_md5.h"
  21.  
  22. #define LF 10
  23. #define CR 13
  24.  
  25. #define MAX_STRING_LEN 256
  26.  
  27. char *tn;
  28.  
  29. static char *strd(char *s)
  30. {
  31.     char *d;
  32.  
  33.     d = (char *) malloc(strlen(s) + 1);
  34.     strcpy(d, s);
  35.     return (d);
  36. }
  37.  
  38. static void getword(char *word, char *line, char stop)
  39. {
  40.     int x = 0, y;
  41.  
  42.     for (x = 0; ((line[x]) && (line[x] != stop)); x++)
  43.     word[x] = line[x];
  44.  
  45.     word[x] = '\0';
  46.     if (line[x])
  47.     ++x;
  48.     y = 0;
  49.  
  50.     while ((line[y++] = line[x++]));
  51. }
  52.  
  53. static int getline(char *s, int n, FILE *f)
  54. {
  55.     register int i = 0;
  56.  
  57.     while (1) {
  58.     s[i] = (char) fgetc(f);
  59.  
  60.     if (s[i] == CR)
  61.         s[i] = fgetc(f);
  62.  
  63.     if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) {
  64.         s[i] = '\0';
  65.         return (feof(f) ? 1 : 0);
  66.     }
  67.     ++i;
  68.     }
  69. }
  70.  
  71. static void putline(FILE *f, char *l)
  72. {
  73.     int x;
  74.  
  75.     for (x = 0; l[x]; x++)
  76.     fputc(l[x], f);
  77.     fputc('\n', f);
  78. }
  79.  
  80.  
  81. static void add_password(char *user, char *realm, FILE *f)
  82. {
  83.     char *pw;
  84.     AP_MD5_CTX context;
  85.     unsigned char digest[16];
  86.     char string[MAX_STRING_LEN];
  87.     unsigned int i;
  88.  
  89.     pw = strd((char *) getpass("New password:"));
  90.     if (strcmp(pw, (char *) getpass("Re-type new password:"))) {
  91.     fprintf(stderr, "They don't match, sorry.\n");
  92.     if (tn)
  93.         unlink(tn);
  94.     exit(1);
  95.     }
  96.     fprintf(f, "%s:%s:", user, realm);
  97.  
  98.     /* Do MD5 stuff */
  99.     sprintf(string, "%s:%s:%s", user, realm, pw);
  100.  
  101.     ap_MD5Init(&context);
  102.     ap_MD5Update(&context, (unsigned char *) string, strlen(string));
  103.     ap_MD5Final(digest, &context);
  104.  
  105.     for (i = 0; i < 16; i++)
  106.     fprintf(f, "%02x", digest[i]);
  107.  
  108.     fprintf(f, "\n");
  109. }
  110.  
  111. static void usage(void)
  112. {
  113.     fprintf(stderr, "Usage: htdigest [-c] passwordfile realm username\n");
  114.     fprintf(stderr, "The -c flag creates a new file.\n");
  115.     exit(1);
  116. }
  117.  
  118. static void interrupted(void)
  119. {
  120.     fprintf(stderr, "Interrupted.\n");
  121.     if (tn)
  122.     unlink(tn);
  123.     exit(1);
  124. }
  125.  
  126. int main(int argc, char *argv[])
  127. {
  128.     FILE *tfp, *f;
  129.     char user[MAX_STRING_LEN];
  130.     char realm[MAX_STRING_LEN];
  131.     char line[MAX_STRING_LEN];
  132.     char l[MAX_STRING_LEN];
  133.     char w[MAX_STRING_LEN];
  134.     char x[MAX_STRING_LEN];
  135.     char command[MAX_STRING_LEN];
  136.     int found;
  137.  
  138.     tn = NULL;
  139.     signal(SIGINT, (void (*)()) interrupted);
  140.     if (argc == 5) {
  141.     if (strcmp(argv[1], "-c"))
  142.         usage();
  143.     if (!(tfp = fopen(argv[2], "w"))) {
  144.         fprintf(stderr, "Could not open passwd file %s for writing.\n",
  145.             argv[2]);
  146.         perror("fopen");
  147.         exit(1);
  148.     }
  149.     printf("Adding password for %s in realm %s.\n", argv[4], argv[3]);
  150.     add_password(argv[4], argv[3], tfp);
  151.     fclose(tfp);
  152.     exit(0);
  153.     }
  154.     else if (argc != 4)
  155.     usage();
  156.  
  157.     tn = tmpnam(NULL);
  158.     if (!(tfp = fopen(tn, "w"))) {
  159.     fprintf(stderr, "Could not open temp file.\n");
  160.     exit(1);
  161.     }
  162.  
  163.     if (!(f = fopen(argv[1], "r"))) {
  164.     fprintf(stderr,
  165.         "Could not open passwd file %s for reading.\n", argv[1]);
  166.     fprintf(stderr, "Use -c option to create new one.\n");
  167.     exit(1);
  168.     }
  169.     strcpy(user, argv[3]);
  170.     strcpy(realm, argv[2]);
  171.  
  172.     found = 0;
  173.     while (!(getline(line, MAX_STRING_LEN, f))) {
  174.     if (found || (line[0] == '#') || (!line[0])) {
  175.         putline(tfp, line);
  176.         continue;
  177.     }
  178.     strcpy(l, line);
  179.     getword(w, l, ':');
  180.     getword(x, l, ':');
  181.     if (strcmp(user, w) || strcmp(realm, x)) {
  182.         putline(tfp, line);
  183.         continue;
  184.     }
  185.     else {
  186.         printf("Changing password for user %s in realm %s\n", user, realm);
  187.         add_password(user, realm, tfp);
  188.         found = 1;
  189.     }
  190.     }
  191.     if (!found) {
  192.     printf("Adding user %s in realm %s\n", user, realm);
  193.     add_password(user, realm, tfp);
  194.     }
  195.     fclose(f);
  196.     fclose(tfp);
  197. #if defined(OS2) || defined(WIN32)
  198.     sprintf(command, "copy \"%s\" \"%s\"", tn, argv[1]);
  199. #else
  200.     sprintf(command, "cp %s %s", tn, argv[1]);
  201. #endif
  202.     system(command);
  203.     unlink(tn);
  204.     exit(0);
  205. }
  206.